import Phaser from 'phaser';

class Snake {
  body: Array<Point>;
  direction: Direction;
  constructor() {
    this.body = [new Point(0, 0)];
    this.direction = Direction.Right;
  }

  move(food: Food) {
    const head = this.body[0];
    const newHead = head.move(this.direction);
    this.body.unshift(newHead);
    if (newHead.equals(food.position)) {
      this.body.push(food.position);
      food.reset();
    } else {
      this.body.pop();
    }
  }
}

enum Direction {
  Up,
  Down,
  Left,
  Right,
}

class Point {
  x: number;
  y: number;
  constructor(x = 0, y = 0) {
    this.x = x;
    this.y = y;
  }
  move(direction: Direction) {
    switch (direction) {
      case Direction.Up:
        return new Point(this.x, this.y - 1);
      case Direction.Down:
        return new Point(this.x, this.y + 1);
      case Direction.Left:
        return new Point(this.x - 1, this.y);
      case Direction.Right:
        return new Point(this.x + 1, this.y);
    }
  }
  equals(other: Point) {
    return this.x === other.x && this.y === other.y;
  }
}

class Food {
  position: Point;
  constructor() {
    this.position = new Point(
      Math.floor(Math.random() * 20),
      Math.floor(Math.random() * 20)
    );
  }
  reset() {
    this.position = new Point(
      Math.floor(Math.random() * 20),
      Math.floor(Math.random() * 20)
    );
  }
}

class GameOverScene extends Phaser.Scene {
  constructor() {
    super('game-over');
  }

  create() {
    this.add.text(
      Number(this.game.config.width) * 0.5,
      Number(this.game.config.height) * 0.5,
      'Game Over',
      { fontSize: 48 }
    );
    this.add.text(
      Number(this.game.config.width) * 0.5,
      Number(this.game.config.height) * 0.75,
      'Press Space to restart',
      { fontSize: 32 }
    );
    const keyboard = this.input.keyboard;
    if (!keyboard) throw new Error('null keyboard');
    keyboard.once(
      'keydown-SPACE',
      () => {
        this.scene.start('play');
      },
      this
    );
  }
}

const config: Phaser.Types.Core.GameConfig = {
  type: Phaser.AUTO,
  parent: 'app',
  width: 800,
  height: 640,
  physics: {
    default: 'arcade',
    arcade: {
      gravity: { y: 200 },
    },
  },
  scene: [GameOverScene],
};

export default new Phaser.Game(config);
